package com.xzj.mybatis.utils;

import lombok.Builder;
import lombok.Getter;

import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @ProjectName: SpringDemo
 * @Package: com.xzj.mybatis.util
 * @ClassName: JdbcTemplate
 * @Author: xzj
 * @Description: 连接数据库工具
 * @Date: 2022/7/22 10:17
 * @Version: 1.0
 */
@Builder
@Getter
public class JdbcTemplate {

    private final Connection connection;

    /**
     * @param sql
     * @return
     * @Author xzj
     * @Description
     * @Date 10:28 2022/7/22
     **/
    public void execute(final String sql) {
        try (PreparedStatement ps = connection.prepareStatement(sql)) {
            ps.execute();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }


    /**
     * @Author xzj
     * @Description 用于执行`INSERT`、`UPDATE`、`DELETE`等DML语句。
     * @Date 14:33 2022/7/26
     * @param sql
     * @param primaryKey 是否要获得主键
     * @param param 参数
     * @return
     **/
    public int update(final String sql, boolean primaryKey,Object... param) {
        try (PreparedStatement ps = primaryKey? connection.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS):connection.prepareStatement(sql)) {
            for (int i = 0; i < param.length; i++) {
                ps.setObject(i+1, param[i]);
            }
            int i = ps.executeUpdate();
            if(i == 1 && primaryKey){
                ResultSet rs = ps.getGeneratedKeys();
                if (rs.next()) {
                    return rs.getInt(1);
                }
            }
            return i;
        } catch (SQLException e) {
            throw new RuntimeException("UPDATE 语句执行错误：" + e);
        }
    }

    /**
     * @Author xzj
     * @Description
     * @Date 14:44 2022/7/26
     * @param sql
     * @param param
     * @return
     **/
    public int update(final String sql,Object... param) {
        return update( sql, false, param);
    }

   /**
    * @Author xzj
    * @Description 批量修改
    * @Date 14:05 2022/7/25
    * @param sqls
    * @param primaryKey
    * @param params
    * @return
    **/
    public int update(final String[] sqls,boolean primaryKey, List<Object[]> params) {
        //如果只是一条SQL
        if(sqls.length == 1){
            return update(sqls[0],primaryKey, params.get(0));
        }
        try {
            connection.setAutoCommit(false);
            for (int i = 0; i < sqls.length; i++) {
                String sql = sqls[i];
                PreparedStatement ps = connection.prepareStatement(sql);
                Object[] objects = params.get(i);
                for (int j = 0; j < objects.length; j++) {
                    ps.setObject(j+1,objects[j]);
                }
                ps.executeUpdate();
            }
            connection.commit();
            return sqls.length;
        } catch (SQLException e) {
            try {
                connection.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }
        return 0;
    }

    public Integer update(String[] psqls, List<Object[]> values) {
        return update( psqls, false, values);
    }

    /**
     * @param sql
     * @param resultType 返回结果类型
     * @param param
     * @return
     * @Author xzj
     * @Description 查询语句返回多个结果集合
     * @Date 11:28 2022/7/22
     **/
    public <T> List<T> queryForList(final String sql, Class<T> resultType, Object... param) {
        ResultSet resultSet = null;
        try (PreparedStatement ps = connection.prepareStatement(sql)) {
            if (param != null && param.length > 0) {
                for (int i = 0; i < param.length; i++) {
                    ps.setObject(i+1, param[i]);
                }
            }
            resultSet = ps.executeQuery();
            List<T> resultList = new ArrayList<>();
            //获取所有字段
            Field[] declaredFields = resultType.getDeclaredFields();
            List<String> names = MapperUtil.getMapperNames(declaredFields);
            //处理结果
            while (resultSet.next()) {
                T t = resultType.newInstance();
                for (int i = 0; i < declaredFields.length; i++) {
                    declaredFields[i].set(t, resultSet.getObject(names.get(i)));
                    resultList.add(t);
                }
            }
            return resultList;
        } catch (SQLException | InstantiationException | IllegalAccessException e) {
            throw new RuntimeException("UPDATE 语句执行错误：" + e);
        } finally {
            if (resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    throw new RuntimeException("关闭resultSet流异常：" + e);
                }
            }
        }
    }

    /**
     * @param sql
     * @param args
     * @param resultType 返回结果类型
     * @return
     * @Author xzj
     * @Description 带条件查询，返回一个结果
     * @Date 11:32 2022/7/22
     **/
    public <T> T queryForObject(final String sql, Class<T> resultType, Object... args) {
        List<T> result = queryForList(sql, resultType, args);
        return result != null && result.size() > 0 ? result.get(0) : null;
    }


}
